import { LinkList } from "../baseClass/LinkList";
import { SortQueue, SortQueueCompare } from "../baseClass/SortQueue";
import { LogType, saveLog } from "../utils/LogUtil";
import { getValue } from "../utils/utls";
import { BOSSGroupIdKey, BOSSLastStruckTimeKey, Hour, Minute } from "../配置/基础配置";
import { loopMongen } from "./FreshMon";

export interface FreshBossData {
    groupId: number;
    interval: number;
    name: string;
    mapId: string;
    x: number;
    y: number;
    range: number;
    num: number;

    //下次刷新时间
    nextFreshTime: number;

}

export function newFreshBossData(groupId: number, map?: TEnvirnoment, set?: any) {
    let flag = !set;

    set = set || {}

    set.groupId = groupId;
    let data: FreshBossData = set as FreshBossData;

    if (flag || !map) {
        return data;
    }

    data.mapId = map.MapID;
    data.name = set.name;

    let width = map.MapWidth;
    let height = map.MapHeight;
    data.x = getValue(set.x, width / 2)
    data.y = getValue(set.y, height / 2)
    let range = Math.max(data.x, data.y);
    data.range = getValue(set.range, range);

    if (data.interval < 1) {
        data.interval = 1;
    }

    return data;
}

export function copyFreshBossData(data: FreshBossData): FreshBossData {
    let newData = newFreshBossData(data.groupId);
    newData.interval = data.interval;
    newData.name = data.name;
    newData.mapId = data.mapId;
    newData.x = data.x;
    newData.y = data.y;
    newData.range = data.range;
    newData.num = 1;
    return newData;
}

export class FreshBoss {
    bossFreshMap: Map<number, FreshBossData>;
    bossFreshQuery: SortQueue<FreshBossData>;

    count: number;

    constructor(MonGenBossSet) {
        let compare: SortQueueCompare<FreshBossData> = (t1: FreshBossData, t2: FreshBossData): number => {
            if (t1.nextFreshTime > t2.nextFreshTime) {
                return 1;
            }
            else if (t1.nextFreshTime === t2.nextFreshTime) {
                return 0
            }
            return -1;
        }
        this.bossFreshQuery = new SortQueue<FreshBossData>(compare);
        this.bossFreshMap = new Map<number, FreshBossData>();

        let flag = this.load();

        let groupId = 1;
        let time = GameLib.TickCount;
        for (let i = 0; i < MonGenBossSet.length; i++) {
            let set = MonGenBossSet[i];
            let map: TEnvirnoment = GameLib.FindMap(set.mapId)

            if (map) {
                let item: FreshBossData = newFreshBossData(groupId, map, set);
                item.nextFreshTime = time;
                this.bossFreshMap.set(groupId, item);

                if (!flag) {
                    this.bossFreshQuery.inQueue(item);
                }

            }
            else {
                saveLog(`${i}刷怪配置不存在`, LogType.FreshMon)
            }
            groupId++;
        }


        if (flag) {
            this.count = 60;
            this.checkBoss();
        }
        else {
            this.count = 0;
        }

        // console.log(`刷怪队列:${this.bossFreshQuery.size}`)
    }

    freshBoss(): void {
        // console.log(`刷怪队列:${this.bossFreshQuery.size}`)
        let item: LinkList<FreshBossData> = this.bossFreshQuery.start;
        let time = GameLib.TickCount;

        while (item) {
            let data: FreshBossData = item.data;
            if (data.nextFreshTime <= time) {
                this.bossFreshQuery.dequeen();


                if (data.num > 0) {
                    let count = loopMongen(data.mapId, data.name, data.x, data.y, data.range, data.num, (list: TActorList) => {
                        if (list && list.Count > 0) {
                            for (let j = 0; j < list.Count; j++) {
                                let actor: TActor = list.Actor(j);
                                actor.SetNVar(BOSSGroupIdKey, data.groupId);
                                // let index=999
                                // actor.SetCheck(index,true)
                                // console.log(`${actor.Name},N变量:${actor.GetNVar(BOSSGroupIdKey)},groupId:${data.groupId}`)
                                // console.log(`${actor.Name},check变量:${actor.GetCheck(index)},index:${index}`)
                            }
                        }
                    })

                    if (count > 0) {
                        console.log(`${data.name}刷新剩余${count}个,groupId:${data.groupId}`);

                        let newData: FreshBossData = copyFreshBossData(data);
                        newData.nextFreshTime = time + 5 * Minute;
                        newData.num = count;
                        this.bossFreshQuery.inQueue(data);
                    }
                }
                item = this.bossFreshQuery.start;
            }
            else {
                break;
            }
        }

        this.checkBoss();
    }

    onBossDie(Envir: TEnvirnoment, ActorObject: TActor, Killer: TActor, Tag: number) {
        if (ActorObject && !ActorObject.IsPlayer()) {
            let groupId = ActorObject.GetNVar(BOSSGroupIdKey)
            if (groupId > 0) {
                // console.log(`${ActorObject.Name}BOSS死亡`)
                let freshData: FreshBossData = this.bossFreshMap.get(groupId);
                let time = GameLib.TickCount;

                let newData: FreshBossData = copyFreshBossData(freshData);
                newData.nextFreshTime = time + freshData.interval * Minute;
                this.bossFreshQuery.inQueue(newData);

            }
        }
    }

    //怪物最终受到伤害触发
    onMonDamage(boss: TActor, source: TActor, Value: number): void {
        // if(boss&&!boss.Death&&!boss.IsPlayer())
        // {
        //     let groupId=boss.GetNVar(BOSSGroupIdKey)
        //     if(groupId>0)
        //     {
        //         boss.SetNVar(BOSSLastStruckTimeKey,GameLib.TickCount);
        //     } 
        // }
    }

    //检查BOSS是否有遗漏
    checkBoss() {
        this.count++;
        if (this.count < 60) {
            return;
        }
        this.count = 0;

        let countMap = new Map<number, number>();

        //统计等待刷新的怪物数量
        this.bossFreshQuery.getAll((data: FreshBossData) => {
            let count = 0
            if (countMap.has(data.groupId)) {
                count = countMap.get(data.groupId);
            }
            count += data.num;
            countMap.set(data.groupId, count);
        })

        //哪些groupId已经被统计了
        let flagMap: Map<number, boolean> = new Map<number, boolean>();

        this.bossFreshMap.forEach((data: FreshBossData, groupId: number) => {
            // console.log(groupId+" "+countMap.get(groupId))
            if (!flagMap.has(groupId)) {
                let map: TEnvirnoment = GameLib.FindMap(data.mapId);
                let list: TActorList = map.GetActorListInRange(data.x, data.y, 9999);

                for (let i = 0; i < list.Count; i++) {
                    let actor: TActor = list.Actor(i);
                    let id: number = actor.GetNVar(BOSSGroupIdKey);
                    // console.log(actor.Name+" "+id)
                    if (id > 0) {
                        flagMap.set(id, true);
                        let count = countMap.get(id) || 0
                        count++;

                        countMap.set(id, count);
                    }
                }
                list.Free();
            }



            let count = countMap.get(groupId) || 0;
            if (count < data.num) {
                let newData: FreshBossData = copyFreshBossData(data);
                newData.num = data.num - count;
                newData.nextFreshTime = GameLib.TickCount + data.interval * Minute;
                console.log(`组${groupId}刷怪有遗漏`)
            }

        });
    }

    save(): void {
        let list = [];
        this.bossFreshQuery.getAll((data) => {
            list.push(data);
        })
        GameLib.R.query = list;
        // console.log(`save:${JSON.stringify(GameLib.R)}`)
    }

    load(): boolean {
        let list = GameLib.R.query;
        // console.log(`load:${JSON.stringify(GameLib.R)}`)
        if (list) {
            for (let i = 0; i < list.length; i++) {
                let item = list[i];
                this.bossFreshQuery.inQueue(item);
            }
        }
        return !!list;
    }
}